package com.example.rssreader.common;

import lombok.Data;
import lombok.experimental.Accessors;

import java.time.Instant;

/**
 * 统一API响应结果类
 * 用于封装所有API接口的返回数据格式
 * 
 * @param <T> 响应数据的泛型类型
 * @author RSS Reader Team
 * @version 1.0.0
 * @since 2024-01-01
 */
@Data
@Accessors(chain = true)
public class ApiResponse<T> {

    /**
     * 响应状态码
     * 200-成功，其他值表示不同的错误类型
     */
    private Integer code;

    /**
     * 响应消息
     * 用于描述操作结果或错误信息
     */
    private String message;

    /**
     * 响应数据
     * 泛型类型，可以是任意类型的数据
     */
    private T data;

    /**
     * 响应时间戳
     * Unix时间戳，表示响应生成的时间
     */
    private Long timestamp;

    /**
     * 私有构造函数
     * 防止外部直接实例化，强制使用静态工厂方法
     */
    private ApiResponse() {
        this.timestamp = Instant.now().toEpochMilli();
    }

    /**
     * 创建成功响应
     * 
     * @param <T> 数据类型
     * @return 成功响应对象
     */
    public static <T> ApiResponse<T> success() {
        return new ApiResponse<T>()
                .setCode(200)
                .setMessage("操作成功");
    }

    /**
     * 创建成功响应并携带数据
     * 
     * @param data 响应数据
     * @param <T>  数据类型
     * @return 成功响应对象
     */
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<T>()
                .setCode(200)
                .setMessage("操作成功")
                .setData(data);
    }

    /**
     * 创建成功响应并携带自定义消息和数据
     * 
     * @param message 响应消息
     * @param data    响应数据
     * @param <T>     数据类型
     * @return 成功响应对象
     */
    public static <T> ApiResponse<T> success(T data ,String message) {
        return new ApiResponse<T>()
                .setCode(200)
                .setMessage(message)
                .setData(data);
    }

    /**
     * 创建失败响应
     * 
     * @param code    错误码
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 失败响应对象
     */
    public static <T> ApiResponse<T> error(Integer code, String message) {
        return new ApiResponse<T>()
                .setCode(code)
                .setMessage(message);
    }

    /**
     * 创建失败响应（使用默认错误码500）
     * 
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 失败响应对象
     */
    public static <T> ApiResponse<T> error(String message) {
        return error(500, message);
    }

    /**
     * 创建参数错误响应
     * 
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 参数错误响应对象
     */
    public static <T> ApiResponse<T> badRequest(String message) {
        return error(400, message);
    }

    /**
     * 创建未授权响应
     * 
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 未授权响应对象
     */
    public static <T> ApiResponse<T> unauthorized(String message) {
        return error(401, message);
    }

    /**
     * 创建资源不存在响应
     * 
     * @param message 错误消息
     * @param <T>     数据类型
     * @return 资源不存在响应对象
     */
    public static <T> ApiResponse<T> notFound(String message) {
        return error(404, message);
    }

    /**
     * 判断响应是否成功
     * 
     * @return true-成功，false-失败
     */
    public boolean isSuccess() {
        return this.code != null && this.code == 200;
    }
}